#pragma once
#include <sys/epoll.h>
// 先实现listen的成功读   再实现ioservice的读

#include "Log.hpp"
using namespace LogMudule;
// 外部是 epoll_ctl   epoll_wait
class epoller // epoll模型
{
public:
    epoller()
    {
        _epfd = ::epoll_create(32);
        if (_epfd < 0)
        {
            perror("epoll_create failed");
            exit(EXIT_FAILURE);
        }
    }

    void Ctrl(int sockfd, uint32_t events, int flag)
    {
        struct epoll_event ev;
        ev.events = events;
        ev.data.fd = sockfd;
        int n = epoll_ctl(_epfd, flag, sockfd, &ev);
        if (n < 0)
        {
            LOG(LogLevel::WARNING) << "epoll_ctl error";
        }
    }

    void Add(int sockfd, uint32_t events)
    {
        Ctrl(sockfd, events, EPOLL_CTL_ADD);
    }

    void Update(int sockfd, uint32_t events)
    {
        Ctrl(sockfd, events, EPOLL_CTL_MOD);
    }

    /*void Modify(int sockfd, bool read, bool write)
    {
        u_int32_t events = (read == true ? EPOLLIN : 0) | (write == true ? EPOLLOUT : 0) | EPOLLET;
        Ctrl(sockfd, events, EPOLL_CTL_MOD);
    }*/

    void Delete(int sockfd)
    {
        int n = epoll_ctl(_epfd, EPOLL_CTL_DEL, sockfd, nullptr);
        if (n < 0)
        {
            LOG(LogLevel::WARNING) << "epoll_ctl error";
        }
    }

    int Wait(int maxevents, struct epoll_event *revents, int timeout) // int epoll_wait(int epfd, struct epoll_event *events,int maxevents, int timeout);
    {
        int n = ::epoll_wait(_epfd, revents, maxevents, timeout);
        return n;
    }

    ~epoller()
    {
    }

private:
    int _epfd = -1;
};